package com.cta.jms;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.activemq.MessageAvailableConsumer;
import org.apache.activemq.web.AjaxListener;
import org.apache.activemq.web.AjaxServlet;
import org.apache.activemq.web.AjaxWebClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.continuation.ContinuationSupport;


public class CDRAjaxSevlet extends AjaxServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Log LOG = LogFactory.getLog(CDRAjaxSevlet.class);
	private int maximumMessages = 100;
	
	@Override
	protected void doMessages(AjaxWebClient client, HttpServletRequest request, HttpServletResponse response)
			throws JMSException, IOException {
		
		  int messages = 0;
	        // This is a poll for any messages

	        long timeout = getReadTimeout(request);
	        if (LOG.isDebugEnabled()) {
	            LOG.debug("doMessage timeout=" + timeout);
	        }

	        Message message = null;
	        message = (Message)request.getAttribute("message"); 
	        
	        synchronized (client) {

	            List consumers = client.getConsumers();
	            MessageAvailableConsumer consumer = (MessageAvailableConsumer)request.getAttribute("consumer");

	            if (message == null) {
	                // Look for a message that is ready to go
	                for (int i = 0; message == null && i < consumers.size(); i++) {
	                    consumer = (MessageAvailableConsumer)consumers.get(i);
	                    if (consumer.getAvailableListener() == null) {
	                        continue;
	                    }
	    
	                    // Look for any available messages
	                    message = consumer.receive(10);
	                    if (LOG.isDebugEnabled()) {
	                        LOG.debug("received " + message + " from " + consumer);
	                    }
	                }
	            }
	            
	            // prepare the response
	            response.setContentType("text/xml");
	            response.setHeader("Cache-Control", "no-cache");
	            
	            if (message == null) {
	                Continuation continuation = ContinuationSupport.getContinuation(request);
	                
	                if (continuation.isExpired()) {  
	                    response.setStatus(HttpServletResponse.SC_OK);
	                    StringWriter swriter = new StringWriter();
	                    PrintWriter writer = new PrintWriter(swriter);
	                    writer.println("<ajax-response>");
	                    writer.print("</ajax-response>");

	                    writer.flush();
	                    String m = swriter.toString();
	                    response.getWriter().println(m); 
	                    
	                    return;
	                }

	                continuation.setTimeout(timeout);
	                continuation.suspend();
	                
	                // Fetch the listeners
	                AjaxListener listener = client.getListener();

	                // register this continuation with our listener.
	                listener.setContinuation(continuation);
	                
	                return;
	            }

	            StringWriter swriter = new StringWriter();
	            PrintWriter writer = new PrintWriter(swriter);
	            
	            Map<MessageAvailableConsumer, String> consumerIdMap = client.getIdMap();
	            Map<MessageAvailableConsumer, String> consumerDestinationNameMap = client.getDestinationNameMap();
	            response.setStatus(HttpServletResponse.SC_OK);
	            writer.println("<ajax-response>");

	            // Send any message we already have
	            if (message != null) {
	                String id = consumerIdMap.get(consumer);
	                String destinationName = consumerDestinationNameMap.get(consumer);
	                writeMessageResponse(writer, message, id, destinationName);
	                
	                messages++;
	            }

	            // Send the rest of the messages
	            for (int i = 0; i < consumers.size() && messages < maximumMessages; i++) {
	                consumer = (MessageAvailableConsumer)consumers.get(i);
	                if (consumer.getAvailableListener() == null) {
	                    continue;
	                }

	                // Look for any available messages
	                while (messages < maximumMessages) {
	                    message = consumer.receiveNoWait();
	                    if (message == null) {
	                        break;
	                    }
	                    messages++;
	                    String id = consumerIdMap.get(consumer);
	                    String destinationName = consumerDestinationNameMap.get(consumer);
	                    writeMessageResponse(writer, message, id, destinationName);
	                }
	            }

	            writer.print("</ajax-response>");

	            writer.flush();
	            String m = swriter.toString();
	            response.getWriter().println(m);
	        }
	}
}
